// Copyright 2022 jeff.li. and/or its affiliates.

#include <gtest/gtest.h>
#include <tbir/runtime/container.h>
#include <tbir/runtime/native_object_registry.h>
#include <tbir/runtime/type_name_traits.h>

namespace tbir::runtime {

    namespace {
        class MyTestNameTraitsV1 {
            int a = 0;
        };

        class MyTestNameTraitsV2 {
            int a = 0;
        };

        class MyTestNameTraitsV3 {
            int a = 0;
        };

        TBIR_REGISTER_TYPE_NAME_TRAITS(MyTestNameTraitsV1);
    }  // namespace
    TBIR_REGISTER_TYPE_NAME_TRAITS(MyTestNameTraitsV2);

    TEST(TypeNameTraits, RegisterGet) {
        TBIR_REGISTER_TYPE_NAME_TRAITS(MyTestNameTraitsV1);
        TBIR_REGISTER_TYPE_NAME_TRAITS(MyTestNameTraitsV2);

        EXPECT_EQ(TypeNameTraits::Get<MyTestNameTraitsV1>(), "MyTestNameTraitsV1");
        EXPECT_EQ(TypeNameTraits::Get<MyTestNameTraitsV2>(), "MyTestNameTraitsV2");
        EXPECT_EQ(TypeNameTraits::Get<MyTestNameTraitsV3>(), "");
    }

    namespace {
        class MyNativeDataExampleXXX {
        public:
            MyNativeDataExampleXXX() {
            }

            ~MyNativeDataExampleXXX() = default;

            String get_content() const {
                return "MyNativeDataExampleXXX";
            }
        };

        TBIR_REGISTER_NATIVE_OBJECT(MyNativeDataExampleXXX)
                .SetConstructor([](PyArgs args) -> std::shared_ptr<void> {
                    MXCHECK_EQ(args.size(), 0) << "[MyNativeDataExampleXXX] Expect 0 arguments but get "
                                               << args.size();
                    return std::make_shared<MyNativeDataExampleXXX>();
                })
                .RegisterFunction("get_content", [](void *self, PyArgs args) -> RTValue {
                    MXCHECK_EQ(args.size(), 0)
                        << "[MyNativeDataExampleXXX][func: get_content] Expect 0 arguments but get "
                        << args.size();
                    return reinterpret_cast<MyNativeDataExampleXXX *>(self)->get_content();
                });
    }  // namespace

    TEST(TypeNameTraits, GetPipelineExample) {
        EXPECT_EQ(TypeNameTraits::Get<MyNativeDataExampleXXX>(), "MyNativeDataExampleXXX");
    }

}  // namespace tbir::runtime
